﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;

namespace psafth.FSR.Lapcounter
{
    public enum MulticastDataType : byte
    {
        HeatObject = 0x01,
        Competitors = 0x02,
        Start = 0x03,
        Pause = 0x04,
        Stop = 0x05,
        NoRace = 0x06
    }

    public class MulticastHelper
    {
        // Convert an object to a byte array
        public static byte[] ObjectToByteArray(object obj)
        {
            if (obj == null)
                return null;
            BinaryFormatter bf = new BinaryFormatter();
            MemoryStream ms = new MemoryStream();
            bf.Serialize(ms, obj);
            return ms.ToArray();
        }

        public static byte[] ObjectToByteArray(object obj, byte type)
        {
            if (obj == null)
                return null;
            BinaryFormatter bf = new BinaryFormatter();
            MemoryStream ms = new MemoryStream();
            bf.Serialize(ms, obj);

            byte[] startVal = new byte[] { type };
            byte[] dataVal = ms.ToArray();

            byte[] sum = new byte[startVal.Length + dataVal.Length];

            startVal.CopyTo(sum, 0);
            dataVal.CopyTo(sum, startVal.Length);

            return sum;
        }

        /// <summary>
        /// Function to get object from byte array
        /// </summary>
        /// <param name="byteArray">byte array to get object</param>
        /// <returns>object</returns>
        public static object ByteArrayToObject(byte[] byteArray)
        {
            try
            {

                byte[] data = byteArray.Skip(1).ToArray();
                // convert byte array to memory stream
                System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(data);

                // create new BinaryFormatter
                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter binaryFormatter
                            = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();

                // set memory stream position to starting point
                memoryStream.Position = 0;

                // Deserializes a stream into an object graph and return as a object.
                switch (byteArray[0])
                {
                    case (byte)MulticastDataType.HeatObject:
                        return (HeatCommand)binaryFormatter.Deserialize(memoryStream);
                        break;

                    case (byte)MulticastDataType.Competitors:
                        return (List<RaceCompetitor>)binaryFormatter.Deserialize(memoryStream);
                        break;

                    case (byte)MulticastDataType.Start:
                        return (StartCommand)binaryFormatter.Deserialize(memoryStream);
                        break;

                    case (byte)MulticastDataType.Pause:
                        return (PauseCommand)binaryFormatter.Deserialize(memoryStream);
                        break;

                    case (byte)MulticastDataType.Stop:
                        return (StopCommand)binaryFormatter.Deserialize(memoryStream);
                        break;

                    case (byte)MulticastDataType.NoRace:
                        return null;
                        break;
                }
            }
            catch (Exception ex)
            {
                // Error
                Console.WriteLine("Exception caught in process: {0}", ex.ToString());
            }

            // Error occured, return null
            return null;
        }
    }
}
